//////////////////////////////////////////////////////////////////
// MattiseOS Kernel
// Date: 2008
// Author: Matthew Iselin
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//////////////////////////////////////////////////////////////////

#ifndef INTRCOMMON_H
#define INTRCOMMON_H

// Macros

// gets an interrupt number for an IRQ
#define INTERRUPT_FROM_IRQ( n ) ( n + 32 )

// gets an IRQ number for an interrupt
#define IRQ_FROM_INTERRUPT( n ) ( n - 32 )

// Types

// layout of stack during an interrupt handler
struct stack_layout
{
	uint32_t gs, fs, es, ds;							// segment descriptors
	uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;	// pushed onto the stack by pusha
	uint32_t intnum, ecode;								// interrupt number and error code
	uint32_t eip, cs, eflags, useresp, ss;				// pushed by CPU when interrupt occurs
} __attribute__((packed));

// a custom handler
typedef void (*custom_interrupt_handler)(struct stack_layout*);

// Prototypes

// installs a custom interrupt handler
void kInstallCustomIntrHandler( uint32_t intnum, custom_interrupt_handler p );

// removes a custom interrupt handler
void kRemoveCustomIntrHandler( uint32_t intnum );

// sets up custom handlers
void kSetupCustomIntrHandlers();

// installs IRQ handling
void kSetupIRQs();

#endif
